package com.tian.core.service.impl;

import java.io.File;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.annotation.Resource;
import javax.servlet.ServletContext;

import org.apache.commons.io.FileUtils;
import org.apache.struts2.ServletActionContext;
import org.hibernate.Query;
import org.hibernate.criterion.DetachedCriteria;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;

import com.tian.core.bean.Condition;
import com.tian.core.bean.ConditionOperate;
import com.tian.core.bean.ConditionType;
import com.tian.core.bean.PageList;
import com.tian.core.bean.Pages;
import com.tian.core.dao.BaseDAO;
import com.tian.core.service.BaseService;


@Service
public class BaseServiceImpl<T> implements BaseService<T> {
	@Resource
	private BaseDAO<T> baseDao;
	
	private Class entityClass;
	
	public void setEntity(Class entityClass){
		this.entityClass=entityClass;
	}

	public T save(T entity) {
		return baseDao.save(entity);
	}

	public void delete(T entity) {
		baseDao.delete(entity);
	}

	public void delete(Integer id) {
		baseDao.delete(id, entityClass);
	}

	public void delete(String[] ids) {
		baseDao.delete(ids, entityClass);
	}

	public void update(T entity) {
		baseDao.update(entity);
	}
	
	public  Integer executeHQL(String hql, Map<Integer, String> params) {
		return baseDao.executeHQL(hql, params);
	}
	
	public T get(Integer id) {
		return baseDao.get(id, entityClass);
	}

	public T load(Integer id) {
		return baseDao.load(id, entityClass);
	}

	public List<T> getListByHQL(String hql) {
		return baseDao.getListByHQL(hql);
	}
	public List<T> getListByHQLCondition(String condition){
		return baseDao.getList(condition, entityClass);
	}
	public T get(String propertyName, Object value) {
		return baseDao.get(propertyName, value, entityClass);
	}

	public List<T> getList(String propertyName, Object value) {
		return baseDao.getList(propertyName, value, entityClass);
	}

	public List<T> getAll(Class entityClass) {
		return baseDao.getAll(entityClass);
	}

	public Long getTotalCount(Class entityClass) {
		return baseDao.getTotalCount(entityClass);
	}

	public Integer getMax(String propertyName,Class entityClass){
		return baseDao.getMax(propertyName,entityClass);
	}
	public boolean isExist(String propertyName, Object value) {
		return baseDao.isExist(propertyName, value, entityClass);
	}
	public boolean isHasChildren(String[] pids){
		return baseDao.isHasChildren(pids, entityClass);
	}
	public void flush() {
		baseDao.flush();
	}

	public void clear() {
		baseDao.clear();
	}

	public void evict(Object object) {
		baseDao.evict(object);
	}

	public PageList findByPages(Pages pages) {
		return baseDao.findByPages(pages, entityClass);
	}
	
	

	public PageList findByPages(List<Condition> conditions, Pages pages ) {
		if(conditions.isEmpty()){
			return baseDao.findByPages(pages, entityClass);
		}else{
			String entityName = entityClass.getName().substring(entityClass.getName().lastIndexOf(".")+1);
			StringBuffer hql = new StringBuffer();
			StringBuffer hqlCount = new StringBuffer();
			StringBuffer hql_condition = new StringBuffer();
			StringBuffer hql_order = new StringBuffer();
			hql.append("from ").append(entityName).append(" as model ").append("where 1=1");
			hqlCount.append("select count(*) from ").append(entityName).append(" as model ").append("where 1=1");
			hql_order.append(" order by ");
			for(Condition condition:conditions){
				if(condition.getType().equals(ConditionType.PROPERTY)){
					if(condition.getOperate().equals(ConditionOperate.LIKE)){
						hql_condition.append(" and model.").append(condition.getName()).append(" like ").append("'%").append(condition.getValue()).append("%'");
					}else if(condition.getOperate().equals(ConditionOperate.EQUAL)) {
						Object obj = condition.getValue();
						if(obj instanceof Integer || obj instanceof Float || obj instanceof Long){
							hql_condition.append(" and model.").append(condition.getName()).append(" = ").append(condition.getValue());
						}else{
							hql_condition.append(" and model.").append(condition.getName()).append(" = '").append(condition.getValue()).append("'");
						}
					}else if(condition.getOperate().equals(ConditionOperate.NOTEQUAL)) {
						Object obj = condition.getValue();
						if(obj instanceof Integer || obj instanceof Float || obj instanceof Long){
							hql_condition.append(" and model.").append(condition.getName()).append(" != ").append(condition.getValue());
						}else{
							hql_condition.append(" and model.").append(condition.getName()).append(" != '").append(condition.getValue()).append("'");
						}
					}else if(condition.getOperate().equals(ConditionOperate.GREATE)) {
						Object obj = condition.getValue();
						if(obj instanceof Integer || obj instanceof Float || obj instanceof Long){
							hql_condition.append(" and model.").append(condition.getName()).append(" > ").append(condition.getValue());
						}else{
							hql_condition.append(" and model.").append(condition.getName()).append(" > '").append(condition.getValue()).append("'");
						}
					}else if(condition.getOperate().equals(ConditionOperate.LITTLE)) {
						Object obj = condition.getValue();
						if(obj instanceof Integer || obj instanceof Float || obj instanceof Long){
							hql_condition.append(" and model.").append(condition.getName()).append(" < ").append(condition.getValue());
						}else{
							hql_condition.append(" and model.").append(condition.getName()).append(" < '").append(condition.getValue()).append("'");
						}
					}else if(condition.getOperate().equals(ConditionOperate.GE)) {
						Object obj = condition.getValue();
						if(obj instanceof Integer || obj instanceof Float || obj instanceof Long){
							hql_condition.append(" and model.").append(condition.getName()).append(" >= ").append(condition.getValue());
						}else{
							hql_condition.append(" and model.").append(condition.getName()).append(" >= '").append(condition.getValue()).append("'");
						}
					}else if(condition.getOperate().equals(ConditionOperate.LE)) {
						Object obj = condition.getValue();
						if(obj instanceof Integer || obj instanceof Float || obj instanceof Long){
							hql_condition.append(" and model.").append(condition.getName()).append(" <= ").append(condition.getValue());
						}else{
							hql_condition.append(" and model.").append(condition.getName()).append(" <= '").append(condition.getValue()).append("'");
						}
					}else if(condition.getOperate().equals(ConditionOperate.IN)) {
						hql_condition.append(" and model.").append(condition.getName()).append(" in (").append(condition.getValue()).append(")");
					}else if(condition.getOperate().equals(ConditionOperate.IN)) {
						hql_condition.append(" and model.").append(condition.getName()).append(" not in (").append(condition.getValue()).append(")");
					}
				}else if(condition.getType().equals(ConditionType.ORDER)){
					if(Condition.ASC.equals(condition.getValue())){
						hql_order.append(" model.").append(condition.getName()).append(" asc,");
					}else if(Condition.DESC.equals(condition.getValue())){
						hql_order.append(" model.").append(condition.getName()).append(" desc,");
					}
				}
				
			}
			String hqlString = "";
			String hqlCountString = "";
			if(hql_order.toString().equals(" order by ")){
				hqlString = hql.append(hql_condition).toString();
			}else{
				hqlString = hql.append(hql_condition).append(hql_order).toString();
			}
			if(hqlString.endsWith(",")){
				hqlString=hqlString.substring(0, hqlString.lastIndexOf(","));
			}
			hqlCountString = hqlCount.append(hql_condition).toString();
			return baseDao.queryHQL(hqlString, hqlCountString, null, pages);
		}
	}

	public PageList findByPages(Pages pages, DetachedCriteria detachedCriteria) {
		return baseDao.findByPages(pages, detachedCriteria);
	}

	public List<T> getListByDetachedCriteria(DetachedCriteria detachedCriteria) {
		return baseDao.getListByDetachedCriteria(detachedCriteria);
	}
	
	public List<T> queryHQL(String hql, Map<Integer, String> params) {
		return baseDao.queryHQL(hql, params);
	}
	
	public List querySQL(String sql, Map<Integer, String> params) {
		return baseDao.querySQL(sql, params);
	}

	public void uploadFile(File sourceFile, String distFileName, String distFilePath) {
		try {
			ServletContext context = ServletActionContext.getServletContext();
			String targetDirectory = context.getRealPath(distFilePath);
			File targetDirectoryFile = new File(targetDirectory);
			if(!targetDirectoryFile.exists()){
				targetDirectoryFile.mkdir();
			}
            File target = new File(targetDirectory, distFileName);
            FileUtils.copyFile(sourceFile, target);            
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

}
